package com.joe.learn.jdk8;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.serializer.SerializerFeature;

import java.math.BigDecimal;
import java.util.*;
import java.util.stream.Collectors;

public class JDK8ListMap {

    public static void main(String[] args) {

        List<Student> studentList = getStudentList();

        // 过滤
        System.out.println("过滤-----");
        List<Student> collect = studentList.stream().filter(x -> x.getAge() == 20).collect(Collectors.toList());
        System.out.println("studentList.size:" + studentList.size());
        System.out.println("collect.size:" + collect.size());
        printJson(collect);

        //统计 reduce  BigDecimal::add 方法引用
        System.out.println("统计1-----");
        Optional<BigDecimal> reduce = studentList.stream().map(x -> x.getLiveAmount() == null ? BigDecimal.ZERO : x.getLiveAmount()).reduce(BigDecimal::add);
        reduce.ifPresent(x -> printJson(x));

        //Student::getLiveAmount 方法引用
        System.out.println("统计2-----");
        BigDecimal reduce1 = studentList.stream().map(Student::getLiveAmount).reduce(BigDecimal.ZERO, (a, b) -> {
            a = a == null ? BigDecimal.ZERO : a;
            b = b == null ? BigDecimal.ZERO : b;
            return a.add(b);
        });
        System.out.println(reduce1);

        //List 转 map
        System.out.println("list 转 map -----");
        Map<Integer, Student> studentMap = studentList.stream().collect(Collectors.toMap(Student::getId, student -> student, (s1, s2) -> s1));
        printJson(studentMap);

        //List 分组转map
        System.out.println("list 分组转map -----");
        Map<String, List<Student>> collectMap = studentList.stream().collect(Collectors.groupingBy(Student::getClassName));
        printJson(collectMap);

        Map<String, List<String>> collectMap2 = studentList.stream().collect(Collectors.groupingBy(Student::getClassName, Collectors.mapping(Student::getName, Collectors.toList())));
        printJson(collectMap);

        //List 最大值与最小值
        System.out.println("list  最大值 -----");
        Optional<Student> collectMax = studentList.stream().collect(Collectors.maxBy(Comparator.comparing(Student::getAge)));

        collectMax.ifPresent(x -> printJson(x));
        System.out.println("list  最小值 -----");
        Optional<Student> collectMin = studentList.stream().collect(Collectors.minBy(Comparator.comparing(Student::getAge)));
        collectMin.ifPresent(x -> printJson(x));

        //List 去重
        System.out.println("list 去重 -----");
        List<Integer> integerList = new ArrayList<>(Arrays.asList(1, 2, 3, 1, 3, 2, 4, 5));
        List<Integer> unique = integerList.stream().collect(
                Collectors.collectingAndThen(
                        Collectors.toCollection(() -> new TreeSet<>(Comparator.comparingLong(x -> x))), ArrayList::new)
        );
        printJson(unique);

    }

    public static void printJson(Object x) {
        System.out.println(JSON.toJSONString(x, SerializerFeature.PrettyFormat));
    }

    private static List<Student> getStudentList() {
        Student student1 = new Student(1, "c1", "20190101", "ruize", 20, "石家庄", new BigDecimal("1200"));
        Student student2 = new Student(2, "c2", "20190102", "kelu", 21, "邯郸", null);
        Student student3 = new Student(3, "c2", "20190103", "monkey", 20, "邢台", new BigDecimal("1300.2"));
        Student student4 = new Student(4, "c1", "20190104", "fumu", 22, "衡水", new BigDecimal("1100.5"));
        Student student5 = new Student(2, "c2", "20190102", "kelu", 21, "邯郸", new BigDecimal("1100"));
        return new ArrayList<Student>(Arrays.asList(student1, student2, student3, student4, student5));
    }

    static class Student {


        private Integer id;

        /**
         * 学号
         */
        private String number;

        /**
         * 班级
         */
        private String className;

        /**
         * 姓名
         */
        private String name;

        /**
         * 年龄
         */
        private Integer age;

        /**
         * 家乡城市
         */
        private String city;

        /**
         * 生活费
         */
        private BigDecimal liveAmount;

        public Student(Integer id, String className, String number, String name, Integer age, String city, BigDecimal liveAmount) {
            this.id = id;
            this.className = className;
            this.number = number;
            this.name = name;
            this.age = age;
            this.city = city;
            this.liveAmount = liveAmount;
        }

        public Integer getId() {
            return this.id;
        }

        public void setId(Integer id) {
            this.id = id;
        }

        /**
         * 获取 学号
         */
        public String getNumber() {
            return this.number;
        }

        /**
         * 设置 学号
         */
        public void setNumber(String number) {
            this.number = number;
        }

        /**
         * 获取 姓名
         */
        public String getName() {
            return this.name;
        }

        /**
         * 设置 姓名
         */
        public void setName(String name) {
            this.name = name;
        }

        /**
         * 获取 年龄
         */
        public Integer getAge() {
            return this.age;
        }

        /**
         * 设置 年龄
         */
        public void setAge(Integer age) {
            this.age = age;
        }

        /**
         * 获取 家乡城市
         */
        public String getCity() {
            return this.city;
        }

        /**
         * 设置 家乡城市
         */
        public void setCity(String city) {
            this.city = city;
        }

        /**
         * 生活费
         */
        public BigDecimal getLiveAmount() {
            return this.liveAmount;
        }

        /**
         * 生活费
         */
        public void setLiveAmount(BigDecimal liveAmount) {
            this.liveAmount = liveAmount;
        }

        /**
         * 获取 班级
         */
        public String getClassName() {
            return this.className;
        }

        /**
         * 设置 班级
         */
        public void setClassName(String className) {
            this.className = className;
        }
    }

}